home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1996 January / macformat-033.iso / mac / Shareware City / Graphics / GifScan 1.6 / Sources / Prefs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  13.1 KB  |  537 lines  |  [TEXT/MMCC]

  1. #include "GifScan.h"
  2.  
  3. #include "DSUserProcs.h"
  4. #include "DSGlobals.h"
  5. #include "Prefs.h"
  6.  
  7. #ifndef __BALLOONS__
  8. #include <Balloons.h>
  9. #endif
  10.  
  11. #ifndef __FOLDERS__
  12. #include <Folders.h>
  13. #endif
  14.  
  15. thePrefsHandle        gPrefs;
  16.  
  17. #define    kDialogID    129
  18. #define kOn            1
  19. #define kOff        0
  20. #define kActive        0
  21. #define kInactive    255
  22. #define kFontsMenu    201
  23.  
  24. #define SIZEOFRESOURCE    30        // Original size of the prefs data in this version 
  25.  
  26. static Boolean        helpOn;
  27.  
  28. enum theDialogItems{ kShowCheckBox = 3,
  29.                      kHexaRadio = 4,
  30.                      kDeciRadio = 5,
  31.                      kPercRadio = 6,
  32.                      kPromptForSave = 8,
  33.                      kForgetTheRest = 9,
  34.                      kFontSizePopup = 10,
  35.                      kFullPath = 12,
  36.                      kFontNamePopup = 13,
  37.                      kSaveHTMLTagToClip = 15,
  38.                      kToggleHelpIcon = 17,
  39.                      kToggleHelpCheckBox = 18 };
  40.  
  41. enum theFontSizesMenu { iNine = 1,
  42.                         iTen,
  43.                         iTwelve,
  44.                         iFourteen,
  45.                         iEighteen,
  46.                         iTwentyFour };
  47.  
  48. static pascal ControlRef SnatchHandle(DialogRef theBox, short theGetItem)
  49. {
  50.     short     itemType;
  51.     Rect     itemRect;
  52.     Handle     theHandle;
  53.     
  54.     GetDialogItem(theBox, theGetItem, &itemType, &theHandle, &itemRect);
  55.     return((ControlRef)theHandle);
  56. }
  57.  
  58. static void ActivateRadios(ControlRef ctlHexa, ControlRef ctlDeci, ControlRef ctlPerc)
  59. {
  60.         HiliteControl(ctlHexa, kActive);
  61.         HiliteControl(ctlDeci, kActive);
  62.         HiliteControl(ctlPerc, kActive);
  63. }
  64.  
  65. static void DeActivateRadios(ControlRef ctlHexa, ControlRef ctlDeci, ControlRef ctlPerc)
  66. {
  67.         HiliteControl(ctlHexa, kInactive);
  68.         HiliteControl(ctlDeci, kInactive);
  69.         HiliteControl(ctlPerc, kInactive);
  70. }
  71.  
  72.  
  73. static void SetFontSizePopupItem(ControlRef thePopup)
  74. {
  75.     switch ( (*gPrefs)->fontSize )
  76.     {
  77.         case 9:
  78.             SetCtlValue(thePopup, iNine);
  79.             break;
  80.         case 10:
  81.             SetCtlValue(thePopup, iTen);
  82.             break;
  83.         case 12:
  84.             SetCtlValue(thePopup, iTwelve);
  85.             break;
  86.         case 14:
  87.             SetCtlValue(thePopup, iFourteen);
  88.             break;
  89.         case 18:
  90.             SetCtlValue(thePopup, iEighteen);
  91.             break;
  92.         case 24:
  93.             SetCtlValue(thePopup, iTwentyFour);
  94.             break;
  95.         default:
  96.             SetCtlValue(thePopup, iNine);
  97.             break;
  98.     }
  99. }
  100.  
  101. static short GetFontSizePopup(ControlRef thePopup)
  102. {
  103.     short    item;
  104.     
  105.     item = GetCtlValue(thePopup);
  106.     
  107.     switch (item)
  108.     {
  109.         case iNine:
  110.             return(9);
  111.             break;
  112.         case iTen:
  113.             return(10);
  114.             break;
  115.         case iTwelve:
  116.             return(12);
  117.             break;
  118.         case iFourteen:
  119.             return(14);
  120.             break;
  121.         case iEighteen:
  122.             return(18);
  123.             break;
  124.         case iTwentyFour:
  125.             return(24);
  126.             break;
  127.         default:
  128.             return(9);
  129.             break;
  130.     }
  131. }
  132.  
  133. static pascal Boolean TheModalFilterProc(DialogRef dialog, EventRecord *dialogEvent, 
  134.                 short *itemHit)
  135. {
  136.     ModalFilterUPP        theModalProc;
  137.     Boolean                handled = false, wasAKey, cmdDown;
  138.     OSErr                err;
  139.     char                theKey;
  140.     WindowRef            window;
  141.  
  142.     wasAKey = (dialogEvent->what == keyDown) || (dialogEvent->what == autoKey);
  143.     
  144.     // Check if user turned on Balloon help in the menubar.
  145.     helpOn = HMGetBalloons();
  146.     if ( helpOn )
  147.         SetCtlValue(SnatchHandle(dialog, kToggleHelpCheckBox), kOn);
  148.     else
  149.         SetCtlValue(SnatchHandle(dialog, kToggleHelpCheckBox), kOff);
  150.     
  151.     if ( dialogEvent->what == updateEvt )
  152.         DoUpdate((WindowRef)dialogEvent->message);
  153.         
  154.     if ( !handled)
  155.     {
  156.         err = GetStdFilterProc(&theModalProc);
  157.         if (err != noErr) ErrorAlert(kErrStringID, eMemError, err, false);
  158.         handled = theModalProc(dialog, dialogEvent, itemHit);
  159.     }
  160.     
  161.     return(handled);
  162. }
  163.  
  164. pascal void SetPreferences(void)
  165. {
  166.     DialogRef    dialog;
  167.     GrafPtr        savePort;
  168.     Boolean        dialogDone, userCancelled, doShow, doSave, doForget, doFullPath, doCopy;
  169.     short        itemHit, newFontSize;
  170.     ControlRef    ctlShow, ctlHexa, ctlDeci, ctlPerc, ctlSave, ctlForget, ctlFontSize;
  171.     ControlRef    ctlFullPath, ctlFontName, ctlHTMLCopy, ctlHelpCheckBox;
  172.     MenuRef        fontMenu;
  173.     Str255        fontString, menuString;
  174.     short        menuLength, i, menuIndex;
  175.     
  176.     GetPort(&savePort);
  177.     SetCursor(&qd.arrow);
  178.     
  179.     // Build font menu before dialog loads
  180.     fontMenu = GetMenu(kFontsMenu);
  181.     AddResMenu(fontMenu, 'FONT');
  182.     menuLength = CountMItems(fontMenu);
  183.     GetFontName((*gPrefs)->fontNum, fontString);
  184.     for ( i = 1; i <= menuLength; i++)
  185.     {
  186.         GetMenuItemText(fontMenu, i, menuString);
  187.         if ( !IUEqualString(menuString, fontString) )
  188.         {
  189.             CheckItem(fontMenu, i, true);
  190.             menuIndex = i;
  191.         }
  192.     }
  193.  
  194.     dialog = GetNewDialog(kDialogID, nil, (WindowPtr)-1L);
  195.     
  196.     SetDialogDefaultItem(dialog, ok);
  197.     SetDialogCancelItem(dialog, cancel);
  198.     
  199.     ctlShow = SnatchHandle(dialog, kShowCheckBox);
  200.     ctlHexa = SnatchHandle(dialog, kHexaRadio);
  201.     ctlDeci = SnatchHandle(dialog, kDeciRadio);
  202.     ctlPerc = SnatchHandle(dialog, kPercRadio);
  203.     ctlSave = SnatchHandle(dialog, kPromptForSave);
  204.     ctlForget = SnatchHandle(dialog, kForgetTheRest);
  205.     ctlFontSize = SnatchHandle(dialog, kFontSizePopup);
  206.     ctlFullPath = SnatchHandle(dialog, kFullPath);
  207.     ctlFontName = SnatchHandle(dialog, kFontNamePopup);
  208.     ctlHTMLCopy = SnatchHandle(dialog, kSaveHTMLTagToClip);
  209.     ctlHelpCheckBox = SnatchHandle(dialog, kToggleHelpCheckBox);
  210.     
  211.     SetCtlValue(ctlShow, (*gPrefs)->showColors);
  212.     SetCtlValue(ctlHexa, (*gPrefs)->hexadecimal);
  213.     SetCtlValue(ctlDeci, (*gPrefs)->decimal);
  214.     SetCtlValue(ctlPerc, (*gPrefs)->percentages);
  215.     SetCtlValue(ctlSave, (*gPrefs)->promptSave);
  216.     SetCtlValue(ctlForget, (*gPrefs)->forget);
  217.     SetCtlValue(ctlFullPath, (*gPrefs)->fullPath);
  218.     SetCtlValue(ctlHTMLCopy, (*gPrefs)->copy);
  219.     
  220.     SetFontSizePopupItem(ctlFontSize);
  221.     
  222.     SetCtlValue(ctlFontName, menuIndex);
  223.     
  224.     doShow = (*gPrefs)->showColors;
  225.     doSave = (*gPrefs)->promptSave;
  226.     doForget = (*gPrefs)->forget;
  227.     doFullPath = (*gPrefs)->fullPath;
  228.     doCopy = (*gPrefs)->copy;
  229.     
  230.     helpOn = HMGetBalloons();
  231.     SetCtlValue(ctlHelpCheckBox, helpOn);
  232.     
  233.     if ( doForget )
  234.     {
  235.         HiliteControl(ctlShow, kInactive);
  236.         DeActivateRadios(ctlHexa, ctlDeci, ctlPerc);
  237.     }
  238.     else
  239.     {
  240.         HiliteControl(ctlShow, kActive);
  241.         if ( doShow )
  242.             ActivateRadios(ctlHexa, ctlDeci, ctlPerc);
  243.         else
  244.             DeActivateRadios(ctlHexa, ctlDeci, ctlPerc);
  245.     }
  246.     
  247.     dialogDone = false;
  248.     SetPort(dialog);
  249.     ShowWindow(dialog);
  250.     
  251.     while ( !dialogDone )
  252.     {
  253.         ModalDialog((ModalFilterUPP)TheModalFilterProc, &itemHit);
  254.         switch (itemHit)
  255.         {
  256.             case ok:
  257.                 userCancelled = false;
  258.                 dialogDone = true;
  259.                 break;
  260.             
  261.             case cancel:
  262.                 userCancelled = true;
  263.                 dialogDone =true;
  264.                 break;
  265.             
  266.             case kForgetTheRest:
  267.                 doForget = !doForget;
  268.                 SetCtlValue(ctlForget, doForget);
  269.                 if ( doForget )
  270.                 {
  271.                     HiliteControl(ctlShow, kInactive);
  272.                     DeActivateRadios(ctlHexa, ctlDeci, ctlPerc);
  273.                 }
  274.                 else
  275.                 {
  276.                     HiliteControl(ctlShow, kActive);
  277.                     if ( doShow )
  278.                         ActivateRadios(ctlHexa, ctlDeci, ctlPerc);
  279.                     else
  280.                         DeActivateRadios(ctlHexa, ctlDeci, ctlPerc);
  281.                 }
  282.                 break;
  283.                 
  284.             case kShowCheckBox:
  285.                 doShow = !doShow;
  286.                 SetCtlValue(ctlShow, doShow);
  287.                 if ( doShow )
  288.                     ActivateRadios(ctlHexa, ctlDeci, ctlPerc);
  289.                 else
  290.                     DeActivateRadios(ctlHexa, ctlDeci, ctlPerc);
  291.                 break;
  292.             
  293.             case kHexaRadio:
  294.                 SetCtlValue(ctlHexa, kOn);
  295.                 SetCtlValue(ctlDeci, kOff);
  296.                 SetCtlValue(ctlPerc, kOff);
  297.                 break;
  298.                 
  299.             case kDeciRadio:
  300.                 SetCtlValue(ctlHexa, kOff);
  301.                 SetCtlValue(ctlDeci, kOn);
  302.                 SetCtlValue(ctlPerc, kOff);
  303.                 break;
  304.             
  305.             case kPercRadio:
  306.                 SetCtlValue(ctlHexa, kOff);
  307.                 SetCtlValue(ctlDeci, kOff);
  308.                 SetCtlValue(ctlPerc, kOn);
  309.                 break;
  310.             
  311.             case kPromptForSave:
  312.                 doSave = !doSave;
  313.                 SetCtlValue(ctlSave, doSave);
  314.                 break;
  315.             
  316.             case kFullPath:
  317.                 doFullPath = !doFullPath;
  318.                 SetCtlValue(ctlFullPath, doFullPath);
  319.                 break;
  320.             
  321.             case kFontNamePopup:
  322.                 // Remove old check item
  323.                 for ( i = 1; i <= menuLength; i++ ) 
  324.                     CheckItem(fontMenu, i, false);
  325.                 break;
  326.             
  327.             case kSaveHTMLTagToClip:
  328.                 doCopy = !doCopy;
  329.                 SetCtlValue(ctlHTMLCopy, doCopy);
  330.                 break;
  331.                 
  332.             case kToggleHelpCheckBox:
  333.                 helpOn = !helpOn;
  334.                 SetCtlValue(ctlHelpCheckBox, helpOn);
  335.                 HMSetBalloons(helpOn);
  336.                 break;
  337.         }
  338.     }    
  339.     
  340.     if ( !userCancelled )
  341.     {
  342.         (*gPrefs)->showColors = GetCtlValue(ctlShow);
  343.         (*gPrefs)->hexadecimal = GetCtlValue(ctlHexa);
  344.         (*gPrefs)->decimal = GetCtlValue(ctlDeci);
  345.         (*gPrefs)->percentages = GetCtlValue(ctlPerc);
  346.         (*gPrefs)->promptSave = GetCtlValue(ctlSave);
  347.         (*gPrefs)->forget = GetCtlValue(ctlForget);
  348.         (*gPrefs)->fullPath = GetCtlValue(ctlFullPath);
  349.         (*gPrefs)->copy = GetCtlValue(ctlHTMLCopy);
  350.         
  351.         newFontSize = GetFontSizePopup(ctlFontSize);
  352.         
  353.         i = GetCtlValue(ctlFontName);
  354.         GetMenuItemText(fontMenu, i, menuString);
  355.         GetFNum(menuString, &(*gPrefs)->fontNum);
  356.     }
  357.     
  358.     DisposeDialog(dialog);
  359.     
  360.     SetPort(savePort);
  361.     
  362.     if ( !userCancelled )
  363.     {
  364.         if ( newFontSize != (*gPrefs)->fontSize )
  365.             UpdateWindowFontSize(newFontSize);
  366.         (*gPrefs)->fontSize = newFontSize;
  367.         UpdateWindowFont((*gPrefs)->fontNum);
  368.     }
  369. }
  370.  
  371. // I am using my own error numbers in these routines, starting at 12900
  372. pascal short GetPrefsFile(void)
  373. {
  374.     OSErr            err;
  375.     Handle            prefResHandle;
  376.     FSSpec            prefsFSSpec;
  377.     Str255            prefsFileName;
  378.     StringHandle     prefStrHandle;
  379.     short             prefRefNum;
  380.     long            prefDirID;
  381.     short            prefVRefNum;
  382.     
  383.     // Get the name of the prefsfile from a resource
  384.     prefStrHandle = GetString(prefsFileNameRsrc);
  385.     if (prefStrHandle != nil)
  386.         BlockMoveData(*prefStrHandle, prefsFileName, (Size)(**prefStrHandle) + 1);
  387.     else 
  388.         ErrorAlert(kErrStringID, eCouldNotWriteResources, 12900, false);
  389.         
  390.     // find the prefs folder's volume reference number and directory ID
  391.     err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, &prefVRefNum, &prefDirID);
  392.     if ( err != noErr ) ErrorAlert(kErrStringID, eCouldNotWriteResources, 12901, false);
  393.     
  394.     // Make an FSSPec for prefsfile 
  395.     err = FSMakeFSSpec(prefVRefNum, prefDirID, prefsFileName, &prefsFSSpec);
  396.  
  397.     if ( err == noErr) 
  398.     {
  399.         // open the preference file, will be closed in next subroutines 
  400.         prefRefNum = FSpOpenResFile(&prefsFSSpec, fsRdWrPerm);
  401.         if (prefRefNum == -1) ErrorAlert(kErrStringID, eCouldNotWriteResources, 12902, false);
  402.         return(prefRefNum);
  403.     }
  404.  
  405.     if ( err == fnfErr ) 
  406.     {
  407.         // Get resources from open application 
  408.         prefResHandle = Get1Resource(kPrefResType, prefsResNum);
  409.         if  (prefResHandle == nil) ErrorAlert(kErrStringID, eCouldNotWriteResources, 12903, false);
  410.     
  411.         // prefs file doesn't already exist, so create it 
  412.         FSpCreateResFile(&prefsFSSpec, prefsCreator, prefsFileType, smSystemScript);
  413.         if ( ResError() != noErr ) 
  414.             ErrorAlert(kErrStringID, eCouldNotWriteResources, 12904, false);
  415.         
  416.         // open the preference file 
  417.         prefRefNum = FSpOpenResFile(&prefsFSSpec, fsRdWrPerm);
  418.         if (prefRefNum == -1) 
  419.             ErrorAlert(kErrStringID, eCouldNotWriteResources, 12905, false);
  420.     
  421.         DetachResource(prefResHandle);
  422.         AddResource(prefResHandle, kPrefResType, prefsResNum, "\p");
  423.         ChangedResource(prefResHandle);
  424.         if ( ResError() != noErr ) 
  425.             ErrorAlert(kErrStringID, eCouldNotWriteResources, 12906, false);
  426.         
  427.         // Close the file 
  428.         CloseResFile(prefRefNum);
  429.         return(prefRefNum);
  430.     }
  431.  
  432.     if ( err != noErr || err != fnfErr)
  433.     {
  434.         ErrorAlert(kErrStringID, eCouldNotWriteResources, 12907, false);
  435.         return(-1);
  436.     }
  437. }
  438.  
  439. pascal Handle ReadPrefData(void)
  440. {
  441.     short            prefRefNum;
  442.     Handle            theData;
  443.     Boolean            oldPrefs;
  444.     
  445.     prefRefNum = GetPrefsFile();
  446.     if (prefRefNum != -1)
  447.     {
  448.         UseResFile(prefRefNum);
  449.         theData = GetResource(kPrefResType, prefsResNum);
  450.         
  451.         // Should check for old preferences here and update if neccessary
  452.         if ( (*((thePrefsHandle)(theData)))->version != PREFSVERSION )
  453.             oldPrefs = true;
  454.         else
  455.             oldPrefs = false;
  456.             
  457.         // If prefs are corrupted, remove from file and make a new file
  458.         // Should be with some sort of checksum, I just use the size.
  459.         if ( ( GetHandleSize(theData) != SIZEOFRESOURCE ) || oldPrefs )
  460.         {
  461.             // Remove the old prefs, avoid an error, make sure it exists
  462.             if ( theData != nil )
  463.             {
  464.                 RemoveResource(theData);
  465.                 DisposeHandle(theData);
  466.             }
  467.             
  468.             // Add the new data to the prefsfile
  469.             theData = NewHandleClear(SIZEOFRESOURCE);
  470.             if ( theData != nil )
  471.             {
  472.                 // Get original resource from application
  473.                 theData = GetNamedResource(kPrefResType, "\pDefaults");
  474.                 if ( ResError() != noErr )
  475.                     ErrorAlert(kErrStringID, eCouldNotWriteResources, 12909, false);
  476.                 
  477.                 UseResFile(prefRefNum);
  478.                 AddResource(theData, kPrefResType, prefsResNum, "\p");
  479.                 ChangedResource(theData);
  480.                 WriteResource(theData);
  481.                 UpdateResFile(prefRefNum);
  482.                 if ( ResError() != noErr )
  483.                     ErrorAlert(kErrStringID, eCouldNotWriteResources, 12910, false);
  484.                 
  485.                 // Throw message at user to tell prefs were messed up and renewed
  486.                 if ( oldPrefs )
  487.                     ErrorAlert(kErrStringID, eNewPrefsVersion, 12911, false);
  488.                 else
  489.                     ErrorAlert(kErrStringID, eCorruptPrefs, 12912, false);
  490.             }
  491.             else    
  492.                 // Couldn't allocate memory for a new handle
  493.                 ErrorAlert(kErrStringID, eMemError, 12913, true);
  494.         }
  495.         
  496.         DetachResource(theData);
  497.         CloseResFile(prefRefNum);
  498.         
  499.         return(theData);
  500.     }
  501.     else
  502.         return(nil);
  503. }
  504.  
  505. pascal Boolean WritePrefData(Handle theData)
  506. {
  507.     short            prefRefNum;
  508.     Handle            tempData;
  509.     Boolean            succes = true;
  510.     
  511.     prefRefNum = GetPrefsFile();
  512.     
  513.     // Make sure we have a file and data to write to it 
  514.     if ( (prefRefNum != -1) && (theData != nil) )
  515.     {
  516.         UseResFile(prefRefNum);
  517.         
  518.         // Remove the old resource with the same number and type 
  519.         tempData = Get1Resource(kPrefResType, prefsResNum);
  520.         if ( tempData != nil )
  521.         {
  522.             RemoveResource(tempData);
  523.             DisposeHandle(tempData);
  524.         }
  525.         
  526.         // Add the new data to the prefsfile 
  527.         AddResource(theData, kPrefResType, prefsResNum, "\p");
  528.         ChangedResource(theData);
  529.         if ( ResError() != noErr )
  530.             ErrorAlert(kErrStringID, eCouldNotWriteResources, 12914, false);
  531.         CloseResFile(prefRefNum);
  532.         return(succes);
  533.     }
  534.     else
  535.         return(!succes);
  536. }
  537.